package com.ikingtech.platform.service.application.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.type.TypeReference;
import com.ikingtech.framework.sdk.application.model.ApplicationPageTemplateDTO;
import com.ikingtech.framework.sdk.application.model.ApplicationQueryParamDTO;
import com.ikingtech.framework.sdk.context.event.SystemInitEvent;
import com.ikingtech.framework.sdk.context.exception.FrameworkException;
import com.ikingtech.framework.sdk.core.response.R;
import com.ikingtech.framework.sdk.core.support.LogHelper;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.framework.sdk.web.annotation.ApiController;
import com.ikingtech.framework.sdk.web.annotation.PostRequest;
import com.ikingtech.platform.service.application.entity.ApplicationPageTemplateDO;
import com.ikingtech.platform.service.application.exception.ApplicationExceptionInfo;
import com.ikingtech.platform.service.application.service.ApplicationPageTemplateService;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;

/**
 * @author tie yan
 */
@Slf4j
@RequiredArgsConstructor
@ApiController(value = "/application/page-template", name = "应用中心-业务模型管理", description = "低代码中心-业务模型管理")
public class ApplicationPageTemplateController {

    private final ApplicationPageTemplateService service;

    @Transactional(rollbackFor = Exception.class)
    @PostRequest(order = 9, value = "/add", summary = "保存模板", description = "保存模板")
    public R<String> add(@Parameter(name = "template", description = "页面模板信息")
                         @RequestBody ApplicationPageTemplateDTO template) {
        ApplicationPageTemplateDO entity = Tools.Bean.copy(template, ApplicationPageTemplateDO.class);
        entity.setId(Tools.Id.uuid());
        entity.setInternalTemplate(false);
        this.service.save(entity);
        return R.ok(entity.getId());
    }

    @Transactional(rollbackFor = Exception.class)
    @PostRequest(order = 10, value = "/delete", summary = "删除模板", description = "删除模板。")
    public R<Object> deleteTemplate(@Parameter(name = "templateId", description = "页面模板编号")
                                    @RequestBody String templateId) {
        this.service.removeById(templateId);
        return R.ok();
    }

    @Transactional(rollbackFor = Exception.class)
    @PostRequest(order = 11, value = "/update", summary = "更新模板", description = "更新模板。")
    public R<Object> updateTemplate(@Parameter(name = "template", description = "页面模板信息")
                                    @RequestBody ApplicationPageTemplateDTO template) {
        if (!this.service.exist(template.getId())) {
            throw new FrameworkException(ApplicationExceptionInfo.PAGE_TEMPLATE_NOT_FOUND);
        }
        ApplicationPageTemplateDO entity = Tools.Bean.copy(template, ApplicationPageTemplateDO.class);
        entity.setInternalTemplate(false);
        this.service.updateById(entity);
        return R.ok();
    }

    @PostRequest(order = 12, value = "/list/page", summary = "分页查询模板", description = "分页查询模板。")
    public R<List<ApplicationPageTemplateDTO>> pageTemplate(@Parameter(name = "queryParam", description = "查询参数")
                                                            @RequestBody ApplicationQueryParamDTO queryParam) {
        return R.ok(this.service.listPage(queryParam).convert(entity -> Tools.Bean.copy(entity, ApplicationPageTemplateDTO.class)));
    }

    @PostRequest(order = 13, value = "/list/all", summary = "全量查询模板", description = "全量查询模板。")
    public R<List<ApplicationPageTemplateDTO>> allTemplate() {
        return R.ok(Tools.Coll.convertList(this.service.list(), entity -> Tools.Bean.copy(entity, ApplicationPageTemplateDTO.class)));
    }

    @EventListener(SystemInitEvent.class)
    @Transactional(rollbackFor = Exception.class)
    public void systemInitEventListener() {
        LogHelper.info("INITIALIZE", "Create application page template.");
        List<String> templateJsons = Tools.Resource.readMulti("page-template/");
        List<ApplicationPageTemplateDTO> templates = Tools.Coll.convertList(templateJsons, Tools.Str::isNotBlank, json -> Tools.Json.toBean(json, new TypeReference<>() {
        }));
        if (Tools.Coll.isNotBlank(templates)) {
            this.service.remove(Wrappers.<ApplicationPageTemplateDO>lambdaQuery().eq(ApplicationPageTemplateDO::getInternalTemplate, true));
            this.service.saveBatch(Tools.Coll.convertList(templates, template -> {
                ApplicationPageTemplateDO entity = Tools.Bean.copy(template, ApplicationPageTemplateDO.class);
                entity.setId(Tools.Id.uuid());
                entity.setInternalTemplate(true);
                return entity;
            }));
        }
    }
}
